/*
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *
 *   版权所有  2014-2015 成都星锐蓝海网络科技有限公司
 *   商业许可请联系  +86-18682011860    QQ:66442834
 *   
 */


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include "xyz_log.h"
#include "wmp.h"
#include "wmpctrl.h"
#include "wtpinfo.h"

#include "wtpnl.h"
#include "global.h"


nsap_orgbrc_t S_nsap_orgbrc = { NULL, NULL };

extern struct sockaddr_in G_wmpaddr;

extern int G_nlksock;    /*  连接AC的套接字  */


static int wmpInitACAddr(void);
static int wmpInitNIF(void);
u_int32_t G_net_mode = 1;

/*
 *这个函数是初始化AP状态的。干了这几件事情：
 * 1、把IP的ID读出来，写入内核。本程序省略了这部分代码。
 * 2、读取了AC的地址，看上去这是一个复杂的过程，所以在本程序里也完全省略了。
 * 3、读取了板子的名称，跟硬件相关，本程序也完全的省略了。
 */
void wmpInit(int *state)
{
	int sulktm = 0;
/* 没有内核部分，不用初始化netlink。
	G_nlksock = wtpnlNewConnect();   
	if (G_nlksock < 1) {
		xyz_log_error("Create NETLINK socket error");
		exit(1);
	}
*/
/* 获得AP的ID后发送到内核里，在弹PORTAL的时候有用。内核部分的代码开源版本里没有。
	if (wtpInfoSendApid2Krn()) {
		xyz_log_error("Send WTP-ID to kernel error");
		exit(1);
	}
*/
         S_nsap_orgbrc.org  = xyz_str_malloc_text(orgid, strlen(orgid));
    S_nsap_orgbrc.brc = xyz_str_malloc_text(brcid, strlen(brcid));
	if (!nsap_orgbrc_test()) {
		xyz_log_debug("Send ORGBRC to kernel");
		wtpInfoSendOrgBrc2Krn();
	}    

	if (wmpInitACAddr()) {
		xyz_log_error("AC address not right");
		exit(1);
	}
	//  下发接口参数
	if (wmpInitNIF()) {
		xyz_log_error("NIF init failed");
		exit(1);
	}
/* 免费版本，省略了这个获取板子名称的复杂步骤。牵扯硬件的东西，都省略了吧。*/
	const char *board = nsap_board_name();
  
	wtpInfoSetBoardName(board, strlen(board));
	sulktm = random() % 10;
	xyz_log_debug("Now will sleep %ds to DSCV-State", sulktm);
	sleep(sulktm);
	*state = WTP_STATE_DSCV; /* 初始化完毕，状态进入发现阶段*/
}

int is_valid_v4ip(const char *s)
{
	int tmp = 0;
	uint32_t ip = 0;

	if (!s) {
		return -1;
	}
	if (sscanf(s, "%d.%d.%d.%d", &tmp, &tmp, &tmp, &tmp) != 4) {
		return -1;
	}
	ip = inet_addr(s);
	if (0 == ip || 0xFFFFFFFF == ip) {
		return -1;
	}
	return 0;
}
/*初始化AC的地址。AC地址是从配置里读取的
 */
static int wmpInitACAddr(void)
{
	char *p = NULL;
	uint32_t acaddr = 0;

//	p = (char *)nsap_dscv_addr_get_addr();
                p = (char *)acip;
	if (is_valid_v4ip(p)) {
		xyz_log_error("AC address %s is invalid value", p);
		return -1;		
	}
	xyz_log_debug("AC address %s", p);
	acaddr = inet_addr(p);
	G_wmpaddr.sin_family = AF_INET;
	G_wmpaddr.sin_addr.s_addr = acaddr;
	G_wmpaddr.sin_port = htons(WMP_CTRL_PORT);

	wtpinfoSetACIPStr(p);
	return 0;
}

#include <ctype.h>

static int wmpInitNIF(void)
{
	char mode[] = "natshell.input.mode";
	char input[] = "natshell.input.name";
	char output[] = "natshell.output.name";
	char buf[1024] = { 0 };
	char *nif, *next, *p;

	NLBUFF nlmsg = NLBUFF_INIT;
	BUFF attr;
	nlmsg.type = NLMSG_TYPE_WAN_IF;

/*  网络模式route/bridge
	if (xyz_uci_get_option(mode, buf, sizeof(buf))) {
		return -1;
	}
  */
        strncpy(buf,"bridge",6);
	xyz_log_debug("get net mode : %s", buf);
	if (!strcmp(buf, "bridge")) {
		G_net_mode = 1;
	} else if (!strcmp(buf, "route")) {
		G_net_mode = 2;
	} else if (!strcmp(buf, "nat")) {
		G_net_mode = 2;
	} else {
		xyz_log_error("Buffer put WAN-NIF string error");
		return -1;
	}
	/*  WAN口    */
	memset(buf, 0, sizeof(buf));
        strncpy(buf,"wlan0",5);
        /*
	if (xyz_uci_get_option(input, buf, sizeof(buf))) {
		return -1;
	}
*/
	p = buf; next = NULL;
	while ((nif = strtok_r(p, " ", &next))) {
		buffInit(&attr, NLMSG_ATTR_NIF_WAN);
		if (buffPutStr(&attr, nif, strlen(nif))) {
			xyz_log_error("Buffer put WAN-NIF string error");
			return -1;
		}
		if (nlbuffPutBuff(&nlmsg, &attr)) {
			xyz_log_error("NETLINK Buffer Put ATTR error");
			return -1;
		}
		p = NULL;
	}
        /* 没有内核部分，也就不用发送了。
	if (wtpnlSendNLBuff(&nlmsg)) {
		xyz_log_error("Send WAN-NIF to kernel error");
		return -1;
	}
        */
	/*  LAN口    */
	memset(buf, 0, sizeof(buf));
        strncpy(buf,"br-lan",6);
        /*
	if (xyz_uci_get_option(output, buf, sizeof(buf))) {
		return 0;
	}
         
	memset(&nlmsg, 0, sizeof(NLBUFF));
	nlmsg.type = NLMSG_TYPE_LAN_IF;

	p = buf; next = NULL;
	while ((nif = strtok_r(p, " ", &next))) {
		buffInit(&attr, NLMSG_ATTR_NIF_LAN);
		if (buffPutStr(&attr, nif, strlen(nif))) {
			xyz_log_error("Buffer put LAN-NIF string error");
			return -1;
		}
		if (nlbuffPutBuff(&nlmsg, &attr)) {
			xyz_log_error("NETLINK Buffer Put ATTR error");
			return -1;
		}
		p = NULL;
	}
	if (wtpnlSendNLBuff(&nlmsg)) {
		xyz_log_error("Send WAN-NIF to kernel error");
		return -1;
	}
         */
	return 0;
}
